package core;
import java.util.*;

/** 
 * A Component is a Chemical Entity that is a chemical building block
 * of all Species
 *
 * @author Charlie Moore
 */
public class Component extends ChemicalEntity {
    
    /**
     * Components can be any of these specific types.
     */
    public static enum CompType {
        /**
         * The total amount of dissolved component is known.
         */
        TOTAL_DISSOLVED, 
        /**
         * The activity of the dissolved component is known.
         */
        FIX_DISSOLVED, 
        /**
         * The component is the redox potential.
         */
        REDOX, 
        /** 
         * The partial pressure of the gas is fixed and known.
         */
        GAS, 
        /** 
         * The solid is present with activity = 1.
         */
        SOLID, 
        /**
         * The component has an adsorbing surface.
         */
        SURFACE,
        /**
         * The type is unknown
         */
        UNKNOWN;

        public String toString() {
            return name().replaceAll("_", " ").toLowerCase();
        }

        public static CompType getValue(String value) {
            try {
                return valueOf(value.replaceAll(" ", "_").toUpperCase());
            } catch (Exception e) {
                return CompType.UNKNOWN;
            }
        }
    }
    
    /**
     * The type of this component.
     */
    private CompType type;
    
    /**
     * Mass balance error (T-Tcalc).
     */
    private double error;

    /**
     * Log of this component's molarity at equilibrium.
     */
    private double freeMolarity;
    
    /**
     * Log of the initial guess at what this component's final free
     * molarity will be.
     */
    private double guess;
        
    /**
     * Mass balance constraint.
     */
    private double totalMolarity;
    
    /**
     * Weight in amu.
     */
    private double weight;

    //=================================
    // Getters and Setters
    //---------------------------------
    
    public boolean isFree() { 
        return type == CompType.TOTAL_DISSOLVED;
    }

    public CompType getType() { return type; }
    public static Vector<String> getTypes() {
        Vector<String> types = new Vector<String>();

        for (CompType c : CompType.values()) {
            types.add(c.toString());
        }
        return types;
    }
    public void setType(CompType newType) {
        type = newType;
        setChanged();
        notifyObservers();
    }
    public void setType(String name) {
        setType(CompType.getValue(name));
    }
    
    public double getError() { return error; }
    public void   setError(double newError) {
        error = newError;
        setChanged();
        notifyObservers();
    }
    
    public double getFreeMolarity() { return freeMolarity; }
    public void   setFreeMolarity(double newMol) {
        freeMolarity = newMol;
        setChanged();
        notifyObservers();
    }
    
    public double getGuess() { return guess; }
    public void   setGuess(double newGuess) {
        guess = newGuess;
        setChanged();
        notifyObservers();
    }
    
    public double getTotalMolarity() { return totalMolarity; }
    public void   setTotalMolarity(double newMol) {
        totalMolarity = newMol;
        setChanged();
        notifyObservers();
    }
    
    public double getWeight() { return weight; }
    public void   setWeight(double newWeight) {
        weight = newWeight;
        setChanged();
        notifyObservers();
    }
    
    /**
     * Returns the Component's data as an XML string.
     */
    public String toString()
    {
        StringBuilder data = new StringBuilder();
        data.append("\t<component>\n\t\t<name>");
        data.append(getName());
        data.append("</name>\n\t\t<type>");
        data.append(getType());
        data.append("</type>\n\t\t<charge>");
        data.append(getCharge());
        data.append("</charge>\n\t\t<total_molarity>");
        data.append(getConc());
        data.append("</total_molarity>\n\t\t<log_free_guess>");
        data.append(getGuess());
        data.append("</log_free_guess>\n\t\t<std_dev>");
        data.append(getStdDev());
        data.append("</std_dev>\n\t</component");
        
        return data.toString();
    }
    
    //========================================
    // Constructors
    //----------------------------------------
    public Component() {}
    public Component(String compName) {
        setName(compName);
    }

}
